import wsUtil from '../index.js';
import { ElMessage } from 'element-plus';

class WebRTCUtil {
  constructor() {
    this.peerConnection = null;
    this.localStream = null;
    this.remoteStream = null;
    this.currentRoomId = null;
    this.targetUserId = null;
    this.isInitiator = false;
    this.pendingCandidates = []; // 缓存早期收到的ICE候选者

    // ICE 服务器配置
    this.iceServers = [
      { urls: 'stun:106.15.177.222:3478' },
      {
        urls: 'turn:106.15.177.222:3478',
        username: 'webrtc', // 需要配置实际的用户名
        credential: '123456' // 需要配置实际的密码
      }
    ];

    // 绑定信令处理方法到 WebSocket 处理器
    this.bindSignalingHandlers();
  }

  /**
   * 绑定信令处理方法
   */
  bindSignalingHandlers() {
    // 这些方法会被 WebSocket handler 调用
    window.webRTCHandlers = {
      joined: this.handleJoined.bind(this),
      peerJoined: this.handlePeerJoined.bind(this),
      offer: this.handleOffer.bind(this),
      answer: this.handleAnswer.bind(this),
      candidate: this.handleCandidate.bind(this),
      rtcError: this.handleRTCError.bind(this)
    };
  }

  /**
   * 初始化 PeerConnection
   */
  initPeerConnection() {
    if (this.peerConnection) {
      this.peerConnection.close();
    }

    this.peerConnection = new RTCPeerConnection({
      iceServers: this.iceServers
    });

    // ICE 候选者事件
    this.peerConnection.onicecandidate = (event) => {
      if (event.candidate) {
        this.sendSignaling('candidate', {
          target: this.targetUserId,
          data: event.candidate
        });
      }
    };

    // 远程流事件
    this.peerConnection.ontrack = (event) => {
      console.log('收到远程流事件:', event);
      console.log('远程流数量:', event.streams.length);
      if (event.streams && event.streams.length > 0) {
        this.remoteStream = event.streams[0];
        console.log('设置远程流:', this.remoteStream);
        console.log('远程流轨道数量:', this.remoteStream.getTracks().length);
        this.remoteStream.getTracks().forEach(track => {
          console.log('远程轨道:', track.kind, track.enabled, track.readyState);
        });
        this.onRemoteStream && this.onRemoteStream(this.remoteStream);
      } else {
        console.warn('没有收到远程流');
      }
    };

    // 连接状态变化
    this.peerConnection.onconnectionstatechange = () => {
      console.log('连接状态:', this.peerConnection.connectionState);
      this.onConnectionStateChange && this.onConnectionStateChange(this.peerConnection.connectionState);
    };
  }

  /**
   * 获取可用设备列表
   * @returns {Promise<Array>} - 可用的视频输入设备列表
   */
  async getAvailableDevices() {
    try {
      const devices = await navigator.mediaDevices.enumerateDevices();
      return devices.filter(device => device.kind === 'videoinput');
    } catch (error) {
      console.error('获取设备列表失败:', error);
      ElMessage.error('无法获取设备列表，请检查权限');
      return [];
    }
  }

  /**
   * 获取本地媒体流
   * @param {boolean} video - 是否包含视频
   * @param {boolean} audio - 是否包含音频
   * @param {string|null} deviceId - 指定的视频设备ID
   */
  async getLocalStream(video = true, audio = true, deviceId = null) {
    try {
      const constraints = { audio };
      if (video) {
        constraints.video = deviceId ? { deviceId: { exact: deviceId } } : true;
      }
      this.localStream = await navigator.mediaDevices.getUserMedia(constraints);
      console.log('获取本地流成功');
      this.onLocalStream && this.onLocalStream(this.localStream);
      return this.localStream;
    } catch (error) {
      console.error('获取本地媒体流失败:', error);
      ElMessage.error(`无法获取媒体流: ${error.message}`);
      throw error;
    }
  }

  /**
   * 加入房间（开始通话）
   * @param {string} sessionId - 会话ID（房间ID）
   * @param {string} targetUserId - 目标用户ID
   * @param {string|null} deviceId - 选择的视频设备ID
   */
  async joinRoom(sessionId, targetUserId, deviceId = null) {
    try {
      this.currentRoomId = sessionId;
      this.targetUserId = targetUserId;
      this.isInitiator = true;

      // 获取本地媒体流
      await this.getLocalStream(true, true, deviceId);

      // 初始化 PeerConnection
      this.initPeerConnection();

      // 添加本地流到 PeerConnection
      if (this.localStream) {
        this.localStream.getTracks().forEach(track => {
          this.peerConnection.addTrack(track, this.localStream);
        });
      }

      // 发送加入房间信令
      this.sendSignaling('join', {
        sessionId: sessionId,
        target: targetUserId
      });

    } catch (error) {
      console.error('加入房间失败:', error);
      ElMessage.error('无法启动通话，请检查摄像头和麦克风权限');
    }
  }

  /**
   * 发送信令消息
   * @param {string} type - 信令类型
   * @param {object} data - 信令数据
   */
  sendSignaling(type, data) {
    const message = {
      type: 'rtc',
      method: type,
      data: data
    };
    console.log('消息体2:' , message)
    wsUtil.sendNotice(message);
  }

  /**
   * 处理加入房间成功
   */
  handleJoined(data) {
    console.log('加入房间成功（原始）:', data);
    this.currentRoomId = data.roomId;
    this.onJoined && this.onJoined(data);
  }

  /**
   * 处理对方加入房间
   */
  async handlePeerJoined(data) {
    console.log('对方加入房间:', data);
    this.targetUserId = data.userId;
    this.isInitiator = false;

    // 如果还没有初始化，现在初始化
    if (!this.peerConnection) {
      await this.getLocalStream();
      this.initPeerConnection();

      if (this.localStream) {
        this.localStream.getTracks().forEach(track => {
          this.peerConnection.addTrack(track, this.localStream);
        });
      }
    }

    this.onPeerJoined && this.onPeerJoined(data);
  }

  /**
   * 创建并发送 Offer
   */
  async createOffer() {
    try {
      const offer = await this.peerConnection.createOffer();
      await this.peerConnection.setLocalDescription(offer);

      this.sendSignaling('offer', {
        target: this.targetUserId,
        data: offer
      });

      console.log('发送 Offer 成功');
    } catch (error) {
      console.error('创建 Offer 失败:', error);
    }
  }

  /**
   * 处理收到的 Offer
   */
  async handleOffer(data) {
    try {
      console.log('收到 Offer:', data);
      console.log('Offer 数据结构:', JSON.stringify(data, null, 2));

      // 设置目标用户ID
      this.targetUserId = data.from;

      // 如果 peerConnection 还没有初始化，先初始化
      if (!this.peerConnection) {
        console.log('初始化 PeerConnection 以处理 Offer');
        await this.getLocalStream();
        this.initPeerConnection();

        if (this.localStream) {
          this.localStream.getTracks().forEach(track => {
            console.log('添加本地轨道到 PeerConnection:', track.kind);
            this.peerConnection.addTrack(track, this.localStream);
          });
        }
      }

      // 获取 offer 数据 - 根据实际数据结构调整
      let offerData;
      if (data.data && data.data.data && data.data.data.type && data.data.data.sdp) {
        // 如果数据在 data.data.data 中（三层嵌套）
        offerData = data.data.data;
      } else if (data.data && data.data.type && data.data.sdp) {
        // 如果数据在 data.data 中
        offerData = data.data;
      } else if (data.type && data.sdp) {
        // 如果数据直接在 data 中
        offerData = data;
      } else {
        throw new Error('无法找到有效的 Offer 数据: ' + JSON.stringify(data));
      }

      console.log('解析的 Offer SDP 数据:', offerData);

      if (!offerData.type || !offerData.sdp) {
        throw new Error('Offer 数据格式无效: ' + JSON.stringify(offerData));
      }

      // 创建 RTCSessionDescription 对象
      const sessionDescription = new RTCSessionDescription(offerData);
      console.log('创建的 SessionDescription:', sessionDescription);

      await this.peerConnection.setRemoteDescription(sessionDescription);
      console.log('设置远程描述成功');

      // 处理缓存的 ICE Candidates
      await this.processPendingCandidates();

      // 创建 Answer
      const answer = await this.peerConnection.createAnswer();
      await this.peerConnection.setLocalDescription(answer);

      // 发送 Answer
      this.sendSignaling('answer', {
        target: data.from,
        data: answer
      });

      console.log('发送 Answer 成功');
    } catch (error) {
      console.error('处理 Offer 失败:', error);
      console.error('错误详情:', error.message);
      this.onError && this.onError(error);
    }
  }

  /**
   * 处理收到的 Answer
   */
  async handleAnswer(data) {
    try {
      console.log('收到 Answer:', data);
      console.log('Answer 数据结构:', JSON.stringify(data, null, 2));

      // 获取 answer 数据 - 根据实际数据结构调整
      let answerData;
      if (data.data && data.data.data && data.data.data.type && data.data.data.sdp) {
        // 如果数据在 data.data.data 中（三层嵌套）
        answerData = data.data.data;
      } else if (data.data && data.data.type && data.data.sdp) {
        // 如果数据在 data.data 中
        answerData = data.data;
      } else if (data.type && data.sdp) {
        // 如果数据直接在 data 中
        answerData = data;
      } else {
        throw new Error('无法找到有效的 Answer 数据: ' + JSON.stringify(data));
      }

      console.log('解析的 Answer SDP 数据:', answerData);

      if (!answerData.type || !answerData.sdp) {
        throw new Error('Answer 数据格式无效: ' + JSON.stringify(answerData));
      }

      // 创建 RTCSessionDescription 对象
      const sessionDescription = new RTCSessionDescription(answerData);
      console.log('创建的 Answer SessionDescription:', sessionDescription);

      await this.peerConnection.setRemoteDescription(sessionDescription);
      console.log('设置远程 Answer 描述成功');

      // 处理缓存的 ICE Candidates
      await this.processPendingCandidates();
    } catch (error) {
      console.error('处理 Answer 失败:', error);
      console.error('错误详情:', error.message);
      this.onError && this.onError(error);
    }
  }

  /**
   * 处理收到的 ICE Candidate
   */
  async handleCandidate(data) {
    try {
      console.log('收到 ICE Candidate:', data);

      // 获取 candidate 数据 - 根据实际数据结构调整
      let candidateData;
      if (data.data && data.data.data) {
        candidateData = data.data.data;
      } else if (data.data) {
        candidateData = data.data;
      } else {
        candidateData = data;
      }

      console.log('解析的 Candidate 数据:', candidateData);

      // 如果 peerConnection 还没有初始化，缓存候选者
      if (!this.peerConnection) {
        console.log('PeerConnection 未初始化，缓存 ICE Candidate');
        this.pendingCandidates.push(candidateData);
        return;
      }

      // 如果远程描述还没有设置，缓存候选者
      if (!this.peerConnection.remoteDescription) {
        console.log('远程描述未设置，缓存 ICE Candidate');
        this.pendingCandidates.push(candidateData);
        return;
      }

      await this.peerConnection.addIceCandidate(new RTCIceCandidate(candidateData));
      console.log('添加 ICE Candidate 成功');
    } catch (error) {
      console.error('添加 ICE Candidate 失败:', error);
      console.error('Candidate 数据:', data);
    }
  }

  /**
   * 处理缓存的 ICE Candidates
   */
  async processPendingCandidates() {
    if (this.pendingCandidates.length === 0) {
      return;
    }

    console.log(`处理 ${this.pendingCandidates.length} 个缓存的 ICE Candidates`);

    for (const candidate of this.pendingCandidates) {
      try {
        await this.peerConnection.addIceCandidate(new RTCIceCandidate(candidate));
        console.log('添加缓存的 ICE Candidate 成功');
      } catch (error) {
        console.error('添加缓存的 ICE Candidate 失败:', error);
      }
    }

    // 清空缓存
    this.pendingCandidates = [];
  }

  /**
   * 处理 RTC 错误
   */
  handleRTCError(data) {
    console.error('WebRTC 错误:', data);
    ElMessage.error(data.message || '通话连接出现错误');
    this.onError && this.onError(data);
  }

  /**
   * 切换摄像头开关
   */
  toggleVideo() {
    if (this.localStream) {
      const videoTrack = this.localStream.getVideoTracks()[0];
      if (videoTrack) {
        videoTrack.enabled = !videoTrack.enabled;
        return videoTrack.enabled;
      }
    }
    return false;
  }

  /**
   * 切换麦克风开关
   */
  toggleAudio() {
    if (this.localStream) {
      const audioTrack = this.localStream.getAudioTracks()[0];
      if (audioTrack) {
        audioTrack.enabled = !audioTrack.enabled;
        return audioTrack.enabled;
      }
    }
    return false;
  }

  /**
   * 结束通话
   */
  endCall() {
    console.log('WebRTCUtil: 结束通话')

    // 关闭本地流
    if (this.localStream) {
      this.localStream.getTracks().forEach(track => track.stop());
      this.localStream = null;
    }

    // 关闭 PeerConnection
    if (this.peerConnection) {
      this.peerConnection.close();
      this.peerConnection = null;
    }

    // 清理状态
    this.currentRoomId = null;
    this.targetUserId = null;
    this.remoteStream = null;
    this.isInitiator = false;
    this.pendingCandidates = []; // 清空缓存的候选者

    console.log('WebRTCUtil: 通话资源清理完成');
    // 不再自动触发 onCallEnded 回调，避免循环调用
    // this.onCallEnded && this.onCallEnded();
  }

  /**
   * 设置事件回调
   */
  setCallbacks(callbacks) {
    this.onLocalStream = callbacks.onLocalStream;
    this.onRemoteStream = callbacks.onRemoteStream;
    this.onJoined = callbacks.onJoined;
    this.onPeerJoined = callbacks.onPeerJoined;
    this.onConnectionStateChange = callbacks.onConnectionStateChange;
    this.onCallEnded = callbacks.onCallEnded;
    this.onError = callbacks.onError;
  }
}

export default new WebRTCUtil();
